package com.lcx.thread.impl;

import com.lcx.thread.BaseThread;

import java.lang.reflect.InvocationTargetException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

public class TaskMission extends BaseThread {

    private boolean isDestory = false;

    private volatile Queue<MissionQueue> missions = new ConcurrentLinkedQueue<>();

    private Thread thread;

    private MissionQueue currentMission;

    @Override
    public void start() {
        if(isDestory) return;
        init();
        lockObj.unLock();
    }

    @Override
    public void stop() {
        lockObj.lock();
    }

    @Override
    public void destory() {
        isDestory=true;
        clearMission();
        MissionQueue missionQueue = currentMission;
        if(missionQueue != null){
            try{
                missionQueue.stopMission();
            }catch (Exception e){}
        }
        lockObj.unLock();
    }

    public void addMission(MissionQueue missionQueue){
        missions.add(missionQueue);
    }

    public void clearMission(){
        missions.clear();
    }

    public void stopAndClear(){
        missions.clear();
        MissionQueue missionQueue = currentMission;
        if(missionQueue != null){
            try{
                missionQueue.stopMission();
            }catch (Exception e){}
        }
    }

    private void init(){
        if(thread == null){
            synchronized (this){
                if(thread == null){
                    thread = new Thread(()->{
                        while(!isDestory){
                            MissionQueue mission = missions.poll();
                            currentMission = mission;
                            if(mission!=null){
                                try{
                                    Object obj = mission.process();
                                    //执行结果回掉
                                    mission.postTodo(obj);
                                }catch (InvocationTargetException e){
                                    Exception exception=e;
                                    while(exception instanceof InvocationTargetException){
                                        exception = (Exception) ((InvocationTargetException)exception).getTargetException();
                                    }
                                    mission.errAction(exception.getMessage());
                                    e.printStackTrace();
                                }catch (Exception e){
                                    //错误回掉
                                    mission.errAction(e.getMessage());
                                    e.printStackTrace();
                                }
                                currentMission = null;
                            }
                            if(missions.isEmpty() && !isDestory) lockObj.lock();
                        }
                    });
                    thread.start();
                }
            }
        }
    }

    public static abstract class MissionQueue{
        protected abstract Object process() throws Exception;
        protected abstract void postTodo(Object obj);
        protected abstract void errAction(String errMsg);
        protected abstract void stopMission();
    }

}
